package com.fang.system.io;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.List;

/**
 * @author fanglingxiao
 * @version 1.0
 * @description TODO
 * @date 2022/7/13 4:29 下午
 **/
public class SocketNIO {
    public static void main(String[] args) throws Exception {
        // 服务端开启监听，接收客户端
        ServerSocketChannel ss = ServerSocketChannel.open();
        ss.bind(new InetSocketAddress(9090));
        // 仅接收客户端，不阻塞！！！
        ss.configureBlocking(false);
        List<SocketChannel> clientList = new ArrayList<>();
        while (true) {
            // 因为设置了blocking参数，所以此时accept是非阻塞的
            // accept  调用内核了：没有客户端连接进来，在BIO 的时候一直卡着，但是在NIO ，不卡着，返回-1，NULL
            // 如果来客户端的连接，accept 返回的是这个客户端的fd  5，client  object
            SocketChannel sc = ss.accept();
            if (sc == null) {
                System.out.println("null...");
            } else {
                sc.configureBlocking(false);
                int port = sc.socket().getPort();
                System.out.println("linking port:" + port);
                clientList.add(sc);
            }
            // 开辟一个堆外缓冲区
            ByteBuffer byteBuffer = ByteBuffer.allocateDirect(4096);

            clientList.forEach(client -> {
                try {
                    int read = client.read(byteBuffer);
                    if (read <= 0) {
                        return;
                    }
                    byteBuffer.flip();
                    byte[] bytes = new byte[byteBuffer.limit()];
                    byteBuffer.get(bytes);
                    String ans = new String(bytes);
                    System.out.println(sc.socket().getPort() + "-" + ans);
                    byteBuffer.clear();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });
        }
    }
}
